use Test::More tests => 56;
#use Test::More qw(no_plan);

use Firepear::Carrot::Lexer;
use Firepear::Carrot::Handler::Tag;
use Firepear::Carrot::Handler::Text;
use Firepear::Carrot::Handler::Trigger;
use Firepear::Carrot::Handler::Verbatim;
use Firepear::Carrot::Handler::VerbatimText;

my $mu = ['[',']',';',"'",'-'];

my %d = ();

$d{tag}  = Firepear::Carrot::Handler::Tag->new( mu => $mu );
$d{text} = Firepear::Carrot::Handler::Text->new( mu => $mu );
$d{trig} = Firepear::Carrot::Handler::Trigger->new( mu => $mu );
$d{verb} = Firepear::Carrot::Handler::Verbatim->new( mu => $mu );
$d{vtxt} = Firepear::Carrot::Handler::VerbatimText->new( mu => $mu );

###############################################################################
############################################# Closing of nested tag and trigger
my $text = "preceeding text [tag foo;bar content content content]]]\nNew para";
my $l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1,
                                                  text => $text} ] );
my $node = minigrammarian($l); ################## chunk 1 - TEXT
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TEXT');
is ($node->{content}, 'preceeding text ');
$node = minigrammarian($l); ###################### chunk 2 - TAG
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TAG');
is ($node->{attrs}[0], 'foo');
is ($node->{attrs}[1], 'bar');
is ($node->{content}, undef);
is ($d{tag}->status, 2);
$node = minigrammarian($l); ##################### chunk 3 - TEXT
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TEXT');
is ($node->{content}, 'content content content');
my $token = $l->fetch; ################## chunk 4 - TAG TERMINAL
is ($token, ']]]');    # handle manually since there's no context stack
is ($d{tag}->handles($token), 1);
$d{tag}->lex($l);
is ($d{tag}->status, 3); ############ chunk 5 - TRIGGER TERMINAL
is ($l->current, ']');
$token = $l->fetch;
is ($token, ']]');
is ($d{trig}->handles($token), 1);
$d{trig}->lex($l);
is ($d{trig}->status, 3);
$l->fetch; # consuming newline
$node = minigrammarian($l); ##################### chunk 6 - TEXT
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TEXT');
is ($node->{content}, 'New para');

###############################################################################
################################################### Verbatim chunk with content
clearstatus();
my $longtext = <<LONGTEXT;
This is content text of a verbatime chunk.
   It is allowed to
       contain
all manner of things

  [[including carrot;markup
    Or at least, faux Carrot markup :D
  ]]
    [[[verbatim even things that look like verbatim chunks ]]]

Yaaaaay! ;;; and comments
LONGTEXT
$text = "[[[verbatim;screen\n$longtext]]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1,
                                               text => $text} ] );
$node = minigrammarian($l); ################# chunk 1 - VERBATIM
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'VERBATIM');
is ($node->{element}, 'verbatim');
is ($node->{refid}, 'screen');
is ($node->{attrs}[0], undef);
is ($d{verb}->status, 2);
$l->fetch; # consuming newline
$node = $d{vtxt}->lex($l); ##################### chunk 2 - TEXT
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'VERBATIMTEXT');
is ($node->{content}, $longtext);
$node = minigrammarian($l); ################# chunk 3 - VERBATIM
is ($node, undef);
is ($d{verb}->status, 3);

###############################################################################
####################################################### Immediately nested tags
clearstatus();
$text = "[foo [bar a;b blah blah]]";
$l = Firepear::Carrot::Lexer->new( files => [ {scalar => 1,
                                               text => $text} ] );
$node = minigrammarian($l); ################# chunk 1 - TAG, INCOMPLETE
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TAG');
is ($node->{element}, 'foo');
is ($node->{attrs}[0], undef);
is ($node->{content}, undef);
is ($d{tag}->status, 2);
$node = minigrammarian($l); ################# chunk 2 - TAG, INCOMPLETE
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TAG');
is ($node->{element}, 'bar');
is_deeply ($node->{attrs}, ['a', 'b']);
is ($d{tag}->status, 2);
$node = minigrammarian($l); ################# chunk 3 - TEXT
is (ref $node, 'HASH', 'should be a hashref');
is ($node->{type}, 'TEXT');
is ($node->{element}, undef);
is ($node->{content}, 'blah blah');
is ($d{text}->status, 1);
$token = $l->fetch; ################## chunk 4 - TAG TERMINAL
is ($token, ']]');    # handle manually since there's no context stack
is ($d{tag}->handles($token), 1);
$d{tag}->lex($l);
is ($d{tag}->status, 3);
is ($l->current, ']');
$token = $l->fetch; ############ chunk 5 - TAG TERMINAL
is ($token, ']');
is ($d{tag}->handles($token), 1);
$d{tag}->lex($l);
is ($d{tag}->status, 3);



###############################################################################

sub minigrammarian {
    my ($l) = @_;
    my @handlers = qw(verb trig tag text);
    my $tok = $l->fetch;
    for my $h (@handlers) {
        next unless $d{$h}->handles($tok);
        my $node = $d{$h}->lex($l);
        return $node;
    }
}

sub clearstatus {
    my @handlers = qw(verb trig tag text vtxt);
    for my $h (@handlers) { $d{$h}->status(0) }
}
